﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FBGraph.Configuration;

namespace FBGraph.ClientGenerator
{
    public partial class Auth : Form
    {
        private class AuthRequest
        {
            public Uri AuthUrl { get; set; }
            public ExtendedPermission PermSet { get; set; }
        }

        private Queue<AuthRequest> queue;

        private const String AUTH_URL_FORMAT = "https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&type=user_agent&display=popup&scope={2}";
        private const String REDIRECT_URI = "http://www.facebook.com/connect/login_success.html";
        
        private static readonly FBGraphConfigurationManager config = new FBGraphConfigurationManager();
        
        public Auth()
        {
            InitializeComponent();

            // permissions need to be split into groups because IE, and consequently the web browser control, can't
            // handle the long urls generated by requesting larger (20+) groups of permissions at once.
            var permSetSize = 14;
            var allPerms = Enum.GetValues(typeof(ExtendedPermission)).Cast<ExtendedPermission>().ToList();
            var requests =
                from p in allPerms
                group p by allPerms.IndexOf(p) / permSetSize into permSet
                select FlattenPermSet(permSet) into permSet
                select new AuthRequest
                {
                    AuthUrl = new Uri(String.Format(AUTH_URL_FORMAT,
                        config.ClientID,
                        REDIRECT_URI,
                        String.Join(",", permSet.ToFieldNames()))),
                    PermSet = permSet
                };

            queue = new Queue<AuthRequest>(requests);
        }

        private ExtendedPermission FlattenPermSet(IEnumerable<ExtendedPermission> permSet)
        {
            var result = default(ExtendedPermission);
            foreach (var p in permSet) result |= p;
            return result;
        }

        private Boolean EnqueuePermSet(ExtendedPermission permSet)
        {
            if (permSet == default(ExtendedPermission)) return false;
            else
            {
                queue.Enqueue(new AuthRequest
                {
                    PermSet = permSet
                });
                return true;
            }
        }

        private void Auth_Load(Object sender, EventArgs e)
        {
            NavToNextRequest();
        }

        private AuthRequest currentRequest;
        private Boolean NavToNextRequest()
        {
            if (queue.Count == 0) return false;
            else
            {
                currentRequest = queue.Dequeue();
                browser.Navigate(currentRequest.AuthUrl);
                return true;
            }
        }

        private void browser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            if (e.Url.ToString().StartsWith(REDIRECT_URI))
            {
                var postHash = e.Url.ToString().Split('#')[1];
                var values = postHash.Split('&').Select(p => p.Split('=')).ToDictionary(p => p[0], p => p[1]);

                SavedAccessToken.Default.GeneratorToken = values["access_token"];
                SavedAccessToken.Default.Permissions |= currentRequest.PermSet;
                SavedAccessToken.Default.Save();

                if(!NavToNextRequest()) this.Close();
            }            
        }
    }
}